package com.example.a_java.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.a_java.common.Result;
import com.example.a_java.entity.RepaymentPlan;
import com.example.a_java.service.RepaymentPlanService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;

/**
 * 还款计划Controller
 */
@Tag(name = "还款计划管理", description = "还款计划管理相关接口")
@RestController
@RequestMapping("/api/v1/repayment/plan")
public class RepaymentPlanController {

    @Autowired
    private RepaymentPlanService repaymentPlanService;

    /**
     * 获取还款计划列表
     */
    @Operation(summary = "获取还款计划列表")
    @GetMapping("/list")
    @PreAuthorize("hasAuthority('loan:repayment:list')")
    public Result list(
            @Parameter(description = "页码") @RequestParam(defaultValue = "1") Integer pageNum,
            @Parameter(description = "每页数量") @RequestParam(defaultValue = "10") Integer pageSize,
            @Parameter(description = "合同编号") @RequestParam(required = false) String contractNo,
            @Parameter(description = "贷款编号") @RequestParam(required = false) String loanNo,
            @Parameter(description = "客户姓名") @RequestParam(required = false) String customerName,
            @Parameter(description = "还款状态") @RequestParam(required = false) Integer repayStatus,
            @Parameter(description = "还款方式") @RequestParam(required = false) String repayMethod,
            @Parameter(description = "开始日期") @RequestParam(required = false) String startDate,
            @Parameter(description = "结束日期") @RequestParam(required = false) String endDate) {
        
        Page<RepaymentPlan> page = repaymentPlanService.getRepaymentPlanPage(
                pageNum, pageSize, contractNo, loanNo, customerName, 
                repayStatus, repayMethod, startDate, endDate);
        
        return Result.success(page);
    }

    /**
     * 获取还款计划详情
     */
    @Operation(summary = "获取还款计划详情")
    @GetMapping("/{planId}")
    @PreAuthorize("hasAuthority('loan:repayment:query')")
    public Result getInfo(@PathVariable Long planId) {
        Map<String, Object> detail = repaymentPlanService.getRepaymentPlanDetail(planId);
        return Result.success(detail);
    }

    /**
     * 通过贷款编号获取还款计划
     */
    @Operation(summary = "通过贷款编号获取还款计划")
    @GetMapping("/loan/{loanNo}")
    @PreAuthorize("hasAuthority('loan:repayment:query')")
    public Result getByLoanNo(@PathVariable String loanNo) {
        Map<String, Object> detail = repaymentPlanService.getRepaymentPlanByLoanNo(loanNo);
        return Result.success(detail);
    }

    /**
     * 获取贷款编号下拉列表
     */
    @Operation(summary = "获取贷款编号下拉列表")
    @GetMapping("/loan-numbers")
    @PreAuthorize("hasAuthority('loan:repayment:query')")
    public Result getLoanNumbers(
            @Parameter(description = "关键字") @RequestParam(required = false) String keyword,
            @Parameter(description = "状态") @RequestParam(required = false) Integer status) {
        
        List<Map<String, Object>> loanNumbers = repaymentPlanService.getLoanNumbers(keyword, status);
        return Result.success(loanNumbers);
    }

    /**
     * 获取客户姓名下拉列表
     */
    @Operation(summary = "获取客户姓名下拉列表")
    @GetMapping("/customer-names")
    @PreAuthorize("hasAuthority('loan:repayment:query')")
    public Result getCustomerNames(
            @Parameter(description = "关键字") @RequestParam(required = false) String keyword) {
        
        List<Map<String, Object>> customerNames = repaymentPlanService.getCustomerNames(keyword);
        return Result.success(customerNames);
    }

    /**
     * 获取还款状态列表
     */
    @Operation(summary = "获取还款状态列表")
    @GetMapping("/statuses")
    @PreAuthorize("hasAuthority('loan:repayment:query')")
    public Result getStatuses() {
        List<Map<String, Object>> statuses = repaymentPlanService.getRepaymentStatuses();
        return Result.success(statuses);
    }

    /**
     * 获取还款方式列表
     */
    @Operation(summary = "获取还款方式列表")
    @GetMapping("/payment-methods")
    @PreAuthorize("hasAuthority('loan:repayment:query')")
    public Result getPaymentMethods() {
        List<Map<String, Object>> methods = repaymentPlanService.getPaymentMethods();
        return Result.success(methods);
    }

    /**
     * 生成还款计划
     */
    @Operation(summary = "生成还款计划")
    @PostMapping("/generate")
    @PreAuthorize("hasAuthority('loan:repayment:add')")
    public Result generate(@RequestBody Map<String, Long> params) {
        Long contractId = params.get("contractId");
        if (contractId == null) {
            return Result.fail("合同ID不能为空");
        }
        
        Map<String, Object> result = repaymentPlanService.generateRepaymentPlan(contractId);
        return Result.success(result);
    }

    /**
     * 批量生成还款计划
     */
    @Operation(summary = "批量生成还款计划")
    @PostMapping("/batch-generate")
    @PreAuthorize("hasAuthority('loan:repayment:add')")
    public Result batchGenerate(@RequestBody Map<String, List<Long>> params) {
        List<Long> contractIds = params.get("contractIds");
        if (contractIds == null || contractIds.isEmpty()) {
            return Result.fail("合同ID列表不能为空");
        }
        
        Map<String, Object> result = repaymentPlanService.batchGenerateRepaymentPlan(contractIds);
        return Result.success(result);
    }

    /**
     * 调整还款计划
     */
    @Operation(summary = "调整还款计划")
    @PutMapping("/adjust")
    @PreAuthorize("hasAuthority('loan:repayment:edit')")
    public Result adjust(@RequestBody Map<String, Object> params) {
        Long planId = Long.valueOf(params.get("planId").toString());
        List<Map<String, Object>> adjustments = (List<Map<String, Object>>) params.get("adjustments");
        String reason = (String) params.get("reason");
        List<String> attachmentUrls = (List<String>) params.get("attachmentUrls");
        
        if (planId == null) {
            return Result.fail("还款计划ID不能为空");
        }
        if (adjustments == null || adjustments.isEmpty()) {
            return Result.fail("调整明细不能为空");
        }
        if (reason == null || reason.isEmpty()) {
            return Result.fail("调整原因不能为空");
        }
        
        Map<String, Object> result = repaymentPlanService.adjustRepaymentPlan(planId, adjustments, reason, attachmentUrls);
        return Result.success(result);
    }

    /**
     * 计算罚息
     */
    @Operation(summary = "计算罚息")
    @PostMapping("/calculate-penalty")
    @PreAuthorize("hasAuthority('loan:repayment:query')")
    public Result calculatePenalty(@RequestBody Map<String, Object> params) {
        Long installmentId = Long.valueOf(params.get("installmentId").toString());
        Integer overdueDays = Integer.valueOf(params.get("overdueDays").toString());
        
        if (installmentId == null) {
            return Result.fail("分期ID不能为空");
        }
        if (overdueDays == null || overdueDays <= 0) {
            return Result.fail("逾期天数必须大于0");
        }
        
        Map<String, Object> result = repaymentPlanService.calculatePenalty(installmentId, overdueDays);
        return Result.success(result);
    }

    /**
     * 获取统计数据
     */
    @Operation(summary = "获取统计数据")
    @GetMapping("/statistics")
    @PreAuthorize("hasAuthority('loan:repayment:query')")
    public Result getStatistics() {
        Map<String, Object> statistics = repaymentPlanService.getStatistics();
        return Result.success(statistics);
    }

    /**
     * 导出还款计划
     */
    @Operation(summary = "导出还款计划")
    @GetMapping("/export")
    @PreAuthorize("hasAuthority('loan:repayment:export')")
    public ResponseEntity<Resource> export(
            @Parameter(description = "合同编号") @RequestParam(required = false) String contractNo,
            @Parameter(description = "贷款编号") @RequestParam(required = false) String loanNo,
            @Parameter(description = "客户姓名") @RequestParam(required = false) String customerName,
            @Parameter(description = "还款状态") @RequestParam(required = false) Integer repayStatus,
            @Parameter(description = "开始日期") @RequestParam(required = false) String startDate,
            @Parameter(description = "结束日期") @RequestParam(required = false) String endDate) {
        
        // 这里应该调用业务层导出Excel文件的方法
        // 为了简单起见，这里直接返回示例文件
        try {
            String filename = "还款计划列表.xlsx";
            // 在实际项目中，这里应该是从业务层获取生成的文件
            Resource resource = new ClassPathResource("templates/repayment_plan_template.xlsx");
            
            return ResponseEntity.ok()
                    .contentType(MediaType.parseMediaType("application/vnd.ms-excel"))
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + URLEncoder.encode(filename, StandardCharsets.UTF_8))
                    .body(resource);
        } catch (Exception e) {
            throw new RuntimeException("导出失败: " + e.getMessage());
        }
    }

    /**
     * 导出还款计划明细
     */
    @Operation(summary = "导出还款计划明细")
    @GetMapping("/export-detail/{planId}")
    @PreAuthorize("hasAuthority('loan:repayment:export')")
    public ResponseEntity<Resource> exportDetail(@PathVariable Long planId) {
        // 这里应该调用业务层导出Excel文件的方法
        // 为了简单起见，这里直接返回示例文件
        try {
            String filename = "还款计划明细.xlsx";
            // 在实际项目中，这里应该是从业务层获取生成的文件
            Resource resource = new ClassPathResource("templates/repayment_plan_detail_template.xlsx");
            
            return ResponseEntity.ok()
                    .contentType(MediaType.parseMediaType("application/vnd.ms-excel"))
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + URLEncoder.encode(filename, StandardCharsets.UTF_8))
                    .body(resource);
        } catch (Exception e) {
            throw new RuntimeException("导出失败: " + e.getMessage());
        }
    }
} 